internal class Class_a
{
	private static readonly int m_a = 257;

	internal static void a(ushort[] A_0, int A_1, byte[] A_2, int A_3)
	{
		_ = a(A_2, A_3) / 16 + 1;
		int num = A_3 - 1;
		int num2 = 0;
		int num3 = ((A_1 < A_3 / 2) ? A_1 : (A_3 / 2));
		A_1 -= num3;
		A_3 -= 2 * num3;
		while (num3-- > 0)
		{
			A_0[num2] = (ushort)((0xFF & A_2[num]) + ((0xFF & A_2[num - 1]) << 8));
			num2++;
			num -= 2;
		}
		if (A_1 > 0 && A_3 % 2 == 1)
		{
			A_0[num2] = (ushort)(0xFFu & A_2[num]);
			num--;
			num2++;
			A_1--;
			A_3--;
		}
		while (A_1-- > 0)
		{
			A_0[num2++] = 0;
		}
	}

	internal static void a(byte[] A_0, int A_1, ushort[] A_2, int A_3)
	{
		int num = A_1 - 1;
		int num2 = 0;
		int num3 = ((A_3 < A_1 / 2) ? A_3 : (A_1 / 2));
		A_3 -= num3;
		A_1 -= 2 * num3;
		while (num3-- > 0)
		{
			A_0[num--] = (byte)(0xFFu & (byte)A_2[num2]);
			A_0[num--] = (byte)(A_2[num2] >> 8);
			num2++;
		}
		if (A_3 > 0 && A_1 % 2 == 1)
		{
			A_0[num--] = (byte)(0xFFu & (byte)A_2[num2]);
			num2++;
			A_3--;
			A_1--;
		}
		while (num-- > 0)
		{
			A_0[num--] = 0;
		}
	}

	internal static void c(ushort[] A_0, ushort[] A_1, ushort[] A_2, ushort[] A_3, int A_4)
	{
		ushort[] array = new ushort[global::Class_a.m_a + 2];
		bool[] array2 = new bool[64];
		ushort[][] array3 = new ushort[16][];
		ushort[] array4 = new ushort[global::Class_a.m_a];
		for (int i = 0; i < 16; i++)
		{
			array3[i] = new ushort[global::Class_a.m_a];
		}
		b(array, A_3, A_4);
		int num = d(A_2, A_4);
		int num2 = ((num < 4) ? 1 : ((num < 16) ? 2 : ((num >= 64) ? 4 : 3)));
		a(array3[0], 1, A_4);
		d(array3[1], A_1, A_4);
		array2[0] = true;
		array2[1] = true;
		for (int j = 2; j < 64; j++)
		{
			array2[j] = false;
		}
		int num3 = 0;
		bool flag = false;
		ushort num4 = (ushort)(1 << num % 16);
		for (int num5 = num; num5 >= 0; num5--)
		{
			if (flag)
			{
				b(array4, array4, A_3, array, A_4);
			}
			num3 <<= 1;
			if (!array2[num3])
			{
				b(array3[num3], array3[num3 / 2], A_3, array, A_4);
				array2[num3] = true;
			}
			if ((A_2[num5 / 16] & num4) > 0)
			{
				num3++;
			}
			num4 = (ushort)((num4 != 1) ? ((ushort)((uint)(num4 >> 1) & 0x7FFFu)) : 32768);
			if (!array2[num3])
			{
				b(array3[num3], array3[num3 - 1], A_1, A_3, array, A_4);
				array2[num3] = true;
			}
			if (num5 == 0 || num3 >= 1 << num2 - 1)
			{
				if (flag)
				{
					b(array4, array4, array3[num3], A_3, array, A_4);
				}
				else
				{
					d(array4, array3[num3], A_4);
				}
				num3 = 0;
				flag = true;
			}
		}
		d(A_0, array4, A_4);
	}

	private static int e(ushort[] A_0, int A_1)
	{
		if ((A_0[A_1 - 1] & 0x8000) > 0)
		{
			return -1;
		}
		int num = A_1 - 1;
		while (num >= 0)
		{
			if (A_0[num] <= 0)
			{
				num--;
				continue;
			}
			return 1;
		}
		return 0;
	}

	private static int b(int A_0)
	{
		A_0--;
		int num = 0;
		while (A_0 > 0)
		{
			num++;
			A_0 >>= 1;
		}
		return num;
	}

	private static int a(byte[] A_0, int A_1)
	{
		int i;
		for (i = 0; i < A_1 && A_0[i] == 0; i++)
		{
		}
		if (i != A_1)
		{
			byte b = A_0[i++];
			int num = 8;
			byte b2 = 128;
			while ((b & b2) == 0)
			{
				num--;
				b2 = (byte)(b2 >> 1);
			}
			return 8 * (A_1 - i) + num;
		}
		return 0;
	}

	private static int d(ushort[] A_0, int A_1)
	{
		ushort num = (ushort)(((A_0[A_1 - 1] & 0x8000) > 0) ? uint.MaxValue : 0u);
		int num2 = A_1 - 1;
		while (num2 >= 0 && A_0[num2] == num)
		{
			num2--;
		}
		if (num2 != -1)
		{
			int num3 = 16;
			int num4 = 32768;
			while (num3 >= 0 && (num4 & (num ^ A_0[num2])) == 0)
			{
				num3--;
				num4 >>= 1;
			}
			return 16 * num2 + num3;
		}
		return 1;
	}

	private static int a(int A_0)
	{
		return 16 * ((A_0 + 1 + 15) / 16);
	}

	private static void c(ushort[] A_0, int A_1, int A_2)
	{
		for (int i = 0; i < A_2; i++)
		{
			A_0[i] = 0;
		}
		A_0[A_1 / 16] = (ushort)(1 << A_1 % 16);
	}

	private static void c(ushort[] A_0, int A_1)
	{
		bool flag = true;
		int i;
		for (i = 0; i < A_1 - 1 && flag; i++)
		{
			A_0[i] = (ushort)(A_0[i] + 1);
			if (A_0[i] > 0)
			{
				flag = false;
			}
		}
		if (flag)
		{
			A_0[i] = (ushort)(A_0[i] + 1);
		}
	}

	private static void b(ushort[] A_0, int A_1)
	{
		int num = 0;
		while (num < A_1)
		{
			A_0[num++] = 0;
		}
	}

	private static void d(ushort[] A_0, ushort[] A_1, int A_2)
	{
		for (int i = 0; i < A_2; i++)
		{
			A_0[i] = A_1[i];
		}
	}

	private static int b(ushort[] A_0, int A_1, int A_2)
	{
		int num = A_2 - 1;
		while (num >= 0)
		{
			if (A_0[num + A_1] <= 0)
			{
				num--;
				continue;
			}
			return num + 1;
		}
		return 0;
	}

	private static ushort a(ushort[] A_0, int A_1, ushort A_2, ushort[] A_3, int A_4, int A_5)
	{
		uint num = 0u;
		if (A_2 <= 0)
		{
			return 0;
		}
		for (int i = 0; i < A_5; i++)
		{
			num += (uint)(A_2 * A_3[i + A_4]);
			num += A_0[i + A_1];
			A_0[i + A_1] = (ushort)num;
			num >>= 16;
		}
		return (ushort)num;
	}

	private static void b(ushort[] A_0, ushort[] A_1, ushort[] A_2, int A_3, int A_4)
	{
		b(A_0, 2 * A_4);
		int num = b(A_2, A_3, A_4);
		for (int i = 0; i < A_4; i++)
		{
			A_0[num + i] = a(A_0, i, A_1[i], A_2, A_3, num);
		}
	}

	private static void c(ushort[] A_0, ushort[] A_1, ushort[] A_2, int A_3)
	{
		uint num = 0u;
		for (int i = 0; i < A_3; i++)
		{
			num += A_1[i];
			num += A_2[i];
			A_0[i] = (ushort)num;
			num >>= 16;
		}
	}

	private static void a(ushort[] A_0, ushort[] A_1, ushort[] A_2, int A_3, int A_4)
	{
		uint num = 1u;
		for (int i = 0; i < A_4; i++)
		{
			num += A_1[i];
			num += (uint)(~A_2[i + A_3] & 0xFFFF);
			A_0[i] = (ushort)num;
			num >>= 16;
		}
	}

	private static void c(ushort[] A_0, ushort[] A_1, int A_2)
	{
		uint num = 0u;
		b(A_0, 2 * A_2);
		int num2 = b(A_1, 0, A_2);
		if (num2 > 0)
		{
			int i;
			for (i = 0; i < num2 - 1; i++)
			{
				A_0[num2 + i] = a(A_0, 2 * i + 1, A_1[i], A_1, i + 1, num2 - i - 1);
			}
			c(A_0, A_0, A_0, 2 * A_2);
			for (i = 0; i < num2; i++)
			{
				num += (uint)(A_1[i] * A_1[i]);
				num += A_0[2 * i];
				A_0[2 * i] = (ushort)num;
				num >>= 16;
				num += A_0[2 * i + 1];
				A_0[2 * i + 1] = (ushort)num;
				num >>= 16;
			}
			A_0[2 * i] = (ushort)num;
		}
	}

	private static void a(ushort[] A_0, int A_1)
	{
		bool flag = true;
		int i;
		for (i = 0; i < A_1 - 1 && flag; i++)
		{
			A_0[i] = (ushort)(A_0[i] - 1);
			if (A_0[i] != ushort.MaxValue)
			{
				flag = false;
			}
		}
		if (flag)
		{
			A_0[i] = (ushort)(A_0[i] - 1);
		}
	}

	private static void b(ushort[] A_0, ushort[] A_1, ushort[] A_2, ushort[] A_3, int A_4)
	{
		ushort[] array = new ushort[2 * global::Class_a.m_a];
		c(array, A_1, A_4);
		a(A_0, array, A_2, A_3, A_4);
	}

	private static void b(ushort[] A_0, ushort[] A_1, int A_2)
	{
		ushort[] array = new ushort[2 * (global::Class_a.m_a + 2)];
		ushort[] array2 = new ushort[2 * (global::Class_a.m_a + 3)];
		ushort[] array3 = new ushort[global::Class_a.m_a + 3];
		int num = d(A_1, A_2);
		int num2 = a(2 * num);
		int num3 = num2 / 16;
		int num4 = (num - 2) / 16;
		c(A_0, num2 - num, A_2 + 2);
		c(A_0, A_2 + 2);
		b(array3, A_2 + 3);
		d(array3, A_1, A_2);
		for (int num5 = 1 + b(num2 - num + 1); num5 > 0; num5--)
		{
			c(array, A_0, A_2 + 2);
			b(array2, array3, array, num4, A_2 + 3);
			c(A_0, A_0, A_0, A_2 + 2);
			a(A_0, A_0, array2, num3 - num4, A_2 + 2);
		}
		c(A_0, A_2 + 2);
		while (true)
		{
			b(array, A_0, array3, A_2 + 2);
			a(array, 2 * (A_2 + 2));
			if (d(array, 2 * (A_2 + 2)) > num2)
			{
				a(A_0, A_2 + 2);
				continue;
			}
			break;
		}
	}

	private static void a(ushort[] A_0, int A_1, int A_2)
	{
		ushort num = (ushort)(((A_1 & 0x8000) > 0) ? uint.MaxValue : 0u);
		A_0[0] = (ushort)A_1;
		for (int i = 1; i < A_2; i++)
		{
			A_0[i] = num;
		}
	}

	private static void b(ushort[] A_0, ushort[] A_1, ushort[] A_2, ushort[] A_3, ushort[] A_4, int A_5)
	{
		ushort[] array = new ushort[2 * global::Class_a.m_a];
		b(array, A_1, A_2, A_5);
		a(A_0, array, A_3, A_4, A_5);
	}

	private static void b(ushort[] A_0, ushort[] A_1, ushort[] A_2, int A_3)
	{
		b(A_0, 2 * A_3);
		int num = b(A_2, 0, A_3);
		for (int i = 0; i < A_3; i++)
		{
			A_0[num + i] = a(A_0, i, A_1[i], A_2, 0, num);
		}
	}

	private static void a(ushort[] A_0, ushort[] A_1, ushort[] A_2, ushort[] A_3, int A_4)
	{
		a(new ushort[global::Class_a.m_a], A_0, A_1, A_2, A_3, A_4);
	}

	private static void a(ushort[] A_0, ushort[] A_1, ushort[] A_2, int A_3, int A_4, int A_5)
	{
		b(A_0, 2 * A_5);
		int num = b(A_2, A_3, A_5);
		for (int i = ((A_4 >= A_5 - 1) ? (A_4 - (A_5 - 1)) : 0); i < A_5; i++)
		{
			int num2 = ((A_4 >= i) ? (A_4 - i) : 0);
			A_0[num + i] = a(A_0, i + num2, A_1[i], A_2, num2 + A_3, (num >= num2) ? (num - num2) : 0);
		}
	}

	private static void a(ushort[] A_0, ushort[] A_1, ushort[] A_2, ushort[] A_3, ushort[] A_4, int A_5)
	{
		ushort[] array = new ushort[2 * (global::Class_a.m_a + 2)];
		ushort[] array2 = new ushort[2 * (global::Class_a.m_a + 2)];
		ushort[] array3 = new ushort[2 * global::Class_a.m_a + 2];
		int num = d(A_3, A_5);
		int num2 = a(2 * num) / 16;
		int num3 = (num - 2) / 16;
		int num4 = num2 - num3 - 3;
		if (num4 < 0)
		{
			num4 = 0;
		}
		b(array3, 2 * A_5 + 2);
		d(array3, A_2, 2 * A_5);
		a(array2, A_4, array3, num3, num4, A_5 + 2);
		for (int i = 0; i < A_5; i++)
		{
			A_0[i] = array2[i + (num2 - num3)];
		}
		a(array, A_0, A_3, A_5);
		a(A_1, A_2, array, 0, A_5);
		while (a(A_1, A_3, A_5) >= 0)
		{
			a(A_1, A_1, A_3, 0, A_5);
			c(A_0, A_5);
		}
	}

	private static int a(ushort[] A_0, ushort[] A_1, int A_2)
	{
		int num = e(A_0, A_2);
		int num2 = e(A_1, A_2);
		if (num > num2)
		{
			return 1;
		}
		if (num < num2)
		{
			return -1;
		}
		int num3 = A_2 - 1;
		while (num3 >= 0 && A_0[num3] == A_1[num3])
		{
			num3--;
		}
		if (num3 == -1)
		{
			return 0;
		}
		if (A_0[num3] > A_1[num3])
		{
			return 1;
		}
		return -1;
	}

	private static void a(ushort[] A_0, ushort[] A_1, ushort[] A_2, int A_3)
	{
		b(A_0, A_3);
		int num = b(A_2, 0, A_3);
		for (int i = 0; i < A_3; i++)
		{
			if (num < A_3 - i)
			{
				A_0[num + i] = a(A_0, i, A_1[i], A_2, 0, num);
			}
			else
			{
				a(A_0, i, A_1[i], A_2, 0, A_3 - i);
			}
		}
	}
}
